package com.jiejie.controller;


import com.jiejie.commons.ServerResponse;
import com.jiejie.entity.*;
import com.jiejie.service.ICustomerService;
import com.jiejie.service.IMovieService;
import com.jiejie.service.IScheduleService;
import com.jiejie.service.ISeatService;
import com.jiejie.util.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.web.bind.annotation.*;

import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 辰广
 * @since 2022-10-05
 */
@RestController
public class SeatController {
    @Resource
    private ISeatService seatService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private IScheduleService scheduleService;
    @Resource
    private IMovieService movieService;
    @Resource
    private ICustomerService customerService;

    private DefaultRedisScript<Long> script;



    @GetMapping("seat/getSelledseat")
    public ServerResponse getSelledSeat(@RequestParam("scheduleId")Integer scheduleId){

        return seatService.getSeatByOrder(scheduleId);
    }


    @PostConstruct
    public void init(){
        script = new DefaultRedisScript<>();
        script.setResultType(Long.class);
        script.setScriptSource(new ResourceScriptSource(new ClassPathResource("niceyoo.lua")));
    }
    @PostMapping("seat/buytickets")
    public ServerResponse luaLockBuyTickets(@RequestParam(value = "movieTicketInfo[]") String[] movieTicketInfo,
                                          @RequestParam(value = "movieTicketNum[]") String[] movieTicketNum,
                                          HttpServletRequest request, HttpServletResponse response){
        System.out.println("============1==============");
        System.out.println("movieTicketInfo"+ Arrays.toString(movieTicketInfo));
        System.out.println("movieTicketNum:"+ Arrays.toString(movieTicketNum));

        // ModelAndView mav=new ModelAndView();
        //再查一次数据库和Redis
        String[] key=new String[movieTicketNum.length];
        String[] value=new String[movieTicketNum.length];
        String[] seatName=new String[movieTicketNum.length];
       /* Object a= redisTemplate.opsForValue().get("seat_2_4排1座");
        System.out.println(a);
        System.out.println(seatService.isSeatByOrder(Integer.parseInt(movieTicketInfo[5]),"4排1座"));
        System.out.println("============11111==============");*/
        for(int i=0;i<movieTicketNum.length;i++){
            key[i]="lock_"+movieTicketInfo[6]+"_"+movieTicketNum[i];
            value[i]=UUID.randomUUID().toString().replace("-","");
            seatName[i]="seat_"+movieTicketInfo[6]+"_"+movieTicketNum[i];
            if (redisTemplate.opsForValue().get(seatName[i])!=null || seatService.isSeatByOrder(Integer.parseInt(movieTicketInfo[6]), movieTicketNum[i])){
                return ServerResponse.fail("座位已被购买",null);
            }
        }
        System.out.println("===========2===============");
        System.out.println(Arrays.toString(key));
        //上锁：一次性
        int indexSeat=0;
        for(int i=0;i<movieTicketNum.length;i++){
            Boolean flag=redisTemplate.opsForValue().setIfAbsent(key[i],value[i],30, TimeUnit.SECONDS);
            System.out.println(flag);
            if(!flag)
                break;
            indexSeat++;
        }
        //业务,判断有没有全部枷锁成功
        int indexSeat2=0;
        long orderDate=0;
        if (indexSeat==movieTicketNum.length){
            for(int i=0;i<movieTicketNum.length;i++){
                if (redisTemplate.opsForValue().get(seatName[i])!=null || seatService.isSeatByOrder(Integer.parseInt(movieTicketInfo[6]), movieTicketNum[i]))
                    indexSeat2++;
            }
            if (indexSeat2==0) {
                orderDate=new Date().getTime();
                for (int i = 0; i < movieTicketNum.length; i++) {
                    Boolean seat = redisTemplate.opsForValue().setIfAbsent(seatName[i], movieTicketNum[i], 10, TimeUnit.MINUTES);
                }
            }
        }
        System.out.println("===========3===============");
        //解锁一次性
        for(int i=0;i<indexSeat;i++){
                Long execute=(Long) redisTemplate.execute(script,Arrays.asList(key[i]),value[i]);
                System.out.println("execute执行结果，1表示执行del，0表示未执行 === " + execute);
        }
        if (indexSeat2==0&&indexSeat==movieTicketNum.length) {
            movieTicketInfo[4]=movieService.getMovieDetailById(scheduleService.getById(movieTicketInfo[6]).getMovieId()).getMovieCname();
            Map<String,Object> map=new HashMap<>();
            map.put("movieTicketInfo",movieTicketInfo);
            map.put("movieTicketNum",movieTicketNum);
            map.put("orderDate",orderDate);
            System.out.println("座位已被锁定");
            return ServerResponse.success("ok", map);
        }
        System.out.println("座位已被购买");
        return ServerResponse.fail("座位已被购买",null);
    }



    @GetMapping("MovieSeat")
    public ModelAndView getMovieSeat(@RequestParam("scheduleId")Integer scheduleId) {

        System.out.println("scheduleId:"+scheduleId);
        Schedule schedule=scheduleService.getById(scheduleId);
        Movie movie=movieService.getMovieDetailById(schedule.getMovieId());

        String day= schedule.getScheduleBeginDate().equals(LocalDate.now()) ?"今天":"明天";
        String dataOne= day+"  "+schedule.getScheduleBeginDate().getMonthValue()+"月"+schedule.getScheduleBeginDate().getDayOfMonth()+"日";

        ModelAndView mav=new ModelAndView();

        mav.addObject("schedule",schedule);
        mav.addObject("movie",movie);
        mav.addObject("dataOne",dataOne);
        mav.setViewName("pages/select_seat");
        return mav;
    }

    @GetMapping("getCustomerTel")
    public ServerResponse getCustomerTel(HttpServletRequest request){
        String token=request.getHeader("token");
        LoginCustomer loginCustomer = TokenUtil.parseToken(token);
        Long customerTel=customerService.getById(loginCustomer.getCustomerId()).getCustomerTel();
        Integer customerId=loginCustomer.getCustomerId();
        Map<String ,Object> map=new HashMap<>();
        map.put("customerId",customerId);
        map.put("customerTel",customerTel);
        return ServerResponse.success("ok",map);
    }
}
